package com.ld.security.auth.common.base.aop;

import com.ld.security.common.core.anno.SubmitMax;
import com.ld.security.common.core.exception.ApiException;
import com.ld.security.common.core.util.*;
import com.ld.security.common.shiro.util.SessionUtil;
import lombok.extern.java.Log;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.Map;

@Component
@Aspect
@Order(1)
@Log
public class SubmitMaxAop {
    private static final String key="RequestMaxAop";

    @Pointcut("@annotation(com.ld.security.common.core.anno.SubmitMax)")
    public void aop() {

    }



    @Around("aop()")
    public Object doAroundAdvice(ProceedingJoinPoint pjp) throws Throwable{
        log.info("提交切面");
        String id =SessionUtil.getSessionId();

        MethodSignature ms = (MethodSignature) pjp.getSignature();
        Method method = ms.getMethod();
        SubmitMax requestMax = AnnotationUtils.findAnnotation(method, SubmitMax.class);
        String key = id + method.hashCode();
        /**
         * 防重复提交  将参数体作为key计算
         *
         * */
        String paramsId = JsonUtil.toJson(pjp.getArgs());
        key = UuidUtil.getId(key+paramsId);

        long max = CountUtil.incr(key, requestMax.locktime());
        if(max >= requestMax.value()) {
            long locktime = CountUtil.ttl(key);
            Map params = AopUtil.getParams(pjp);
            params.put("locktime", locktime);
            String errorMsg =TemplateUtil.renderString(requestMax.errorMsg(), params);
            ApiException.throw400(errorMsg);
        }
        Object val = pjp.proceed();
        return val;
    }

}